Skip to content

refactor(audience): centralise SDK runtime constants and message envelope keys (SDK-277)#725

Open
ImmutableJeffrey wants to merge 13 commits intomainfrom
chore/sdk-272-pr-1-sdk-runtime-constants
Open

refactor(audience): centralise SDK runtime constants and message envelope keys (SDK-277)#725
ImmutableJeffrey wants to merge 13 commits intomainfrom
chore/sdk-272-pr-1-sdk-runtime-constants

Conversation

@ImmutableJeffrey
Copy link
Copy Markdown
Collaborator

@ImmutableJeffrey ImmutableJeffrey commented May 3, 2026

Summary

  • Adds [InternalsVisibleTo("Immutable.Audience.Samples.SampleApp.Tests")] grants in examples/audience/Assets/SampleApp/Scripts/AssemblyInfo.cs (new) and src/Packages/Audience/Runtime/AssemblyInfo.cs so the upcoming SSOT centralisation lets SampleApp.Tests compile incrementally against runtime and sample-app internals (AudiencePaths, EventNames, EventPropertyKeys, MessageFields, SampleAppUi, etc.).
  • Names HTTP MIME, Content-Encoding header, and gzip encoding constants in Constants.cs.
  • Names HTTP request timeout and the four-step backoff schedule in HttpTransport.
  • Replaces the magic literal 429 with HttpStatusCode.TooManyRequests.
  • Names session timer-disposal budgets (heartbeat drain, start drain) in Session.
  • Names consent-sync retry budgets (max attempts, base retry interval) in ImmutableAudience.
  • Names queue file glob and atomic-write tmp suffix in AudiencePaths.
  • Names JSON timestamp ("o") and round-trip ("R") number formats in Constants.cs.
  • Adds ResponseFields and ConsentBodyFields for the consent-sync PUT body and the accepted/rejected response shape.
  • Expands MessageFields with the full envelope key set (Type, MessageId, EventTimestamp, Context, Surface, EventName, Properties, AnonymousId, UserId, IdentityType, Traits, FromId, FromType, ToId, ToType, Library, LibraryVersion).
  • Adds EventNames for SDK-emitted event names (session_start, session_heartbeat, session_end, game_launch).
  • Adds EventPropertyKeys for SDK-emitted event property keys.
  • Adds ContextKeys and GameLaunchPropertyKeys for the context dictionary and game_launch payload; routes DeviceCollector strings through Constants.MaxFieldLength.
  • No behaviour change. Wire format and OnError callback contract unchanged.

Linear: SDK-277

@ImmutableJeffrey ImmutableJeffrey requested review from a team as code owners May 3, 2026 07:17
@ImmutableJeffrey ImmutableJeffrey force-pushed the chore/sdk-272-pr-1-sdk-runtime-constants branch from fba80b5 to 34d4050 Compare May 3, 2026 07:40
…pass

Adds InternalsVisibleTo grants the upcoming SSOT centralisation needs so SampleApp
tests compile incrementally as constants are introduced.

- examples/audience/Assets/SampleApp/Scripts/AssemblyInfo.cs (new): grants
  SampleApp.Tests access to sample-app internals (SampleAppUi,
  SampleAppCustomEvents, SampleAppCustomEventPropertyKeys).
- src/Packages/Audience/Runtime/AssemblyInfo.cs: grants SampleApp.Tests access
  to SDK runtime internals (AudiencePaths, EventNames, EventPropertyKeys,
  MessageFields).
…nstants

Replaces "application/json" / "gzip" / "Content-Encoding" string
literals with Constants.MediaTypeJson / GzipEncoding /
ContentEncodingHeader so the messages POST and the consent-sync PUT
share one source of truth and the test assertions read from the same
constants.

- Constants.cs: adds MediaTypeJson, GzipEncoding, ContentEncodingHeader.
- HttpTransport.cs: gzip and plain JSON content paths use the new constants.
- ImmutableAudience.cs: consent-sync PUT body uses MediaTypeJson.
- HttpTransportTests.cs: gzip and plain JSON assertions read from MediaTypeJson and GzipEncoding.
Replaces inline 30-second timeout and the 5/10/20/40/60-second backoff ladder with named constants
on HttpTransport so the schedule is visible at the top of the class and a tuning change touches one
place.

- HttpTransport.cs: adds RequestTimeoutSeconds (30) and Backoff{1st,2nd,3rd,4th,Cap}Ms (5k / 10k /
  20k / 40k / 60k).
- HttpTransport.cs: constructor uses RequestTimeoutSeconds; BackoffMsLocked returns the named
  constants.
… HTTP 429

Drops the inline 429 magic number on both the messages POST retry path and the consent-sync PUT
retry path in favour of the named HttpStatusCode value, so a future RFC change or reading hand stays
in sync with the BCL.

- HttpTransport.cs: messages POST 429 branch reads HttpStatusCode.TooManyRequests.
- ImmutableAudience.cs: consent-sync PUT retry condition reads HttpStatusCode.TooManyRequests; adds
  using System.Net.
Replaces the inline 500ms double-Start drain budget and the 1s heartbeat drain budget in Session
with named constants, so the "quits must not hang" budget is visible at the top of the class and a
tuning change touches one place.

- Session.cs: adds HeartbeatDrainTimeoutMs (1000) and StartDrainTimeoutMs (500).
- Session.cs: Start uses StartDrainTimeoutMs for the prior heartbeat timer drain;
  DrainHeartbeatTimer uses HeartbeatDrainTimeoutMs.
Replaces the inline 4-attempt cap and 1-second base retry on the consent-sync PUT retry loop with
named constants on ImmutableAudience so the budget is visible at the top of the class and a tuning
change touches one place.

- ImmutableAudience.cs: adds ConsentSyncMaxAttempts (4) and ConsentSyncBaseRetryMs (1000).
- ImmutableAudience.cs: SyncConsentLevel uses ConsentSyncMaxAttempts and ConsentSyncBaseRetryMs in
  the 429 retry loop.
Replaces the hand-rolled "*.json" globs and ".tmp" atomic-write suffixes spread across DiskStore,
ConsentStore, Identity, and the test suite with named constants on AudiencePaths so a rename of
either pattern touches one file and runtime / tests stay in sync.

- AudiencePaths.cs: adds QueueFileExtension (.json), QueueGlob ("*.json"), TempFileSuffix (.tmp).
- DiskStore.cs: queueDir uses AudiencePaths.QueueDir; the "*.json" globs and ".tmp" suffix go
  through the new constants; new file naming uses QueueFileExtension.
- ConsentStore.cs, Identity.cs: atomic-write tmpPath uses AudiencePaths.TempFileSuffix.
- Test suite (DiskStoreTests, SessionTests, ImmutableAudienceTests, ThreadSafetyStressTests):
  Directory.GetFiles globs read from AudiencePaths.QueueGlob.
- SampleAppLiveFireTests.cs: SDK persistence dir comes from AudiencePaths.AudienceDir, so the
  sample-app side no longer needs its own SdkPersistedDirName mirror.
…mats

Replaces the bare format-spec strings "o" and "R" passed to DateTime and float / double ToString
calls with named constants on Constants so the wire-shape requirement reads as a contract rather
than a mystery character.

- Constants.cs: adds IsoTimestampFormat ("o") and RoundTripNumberFormat ("R") with comments noting
  the backend schema requirement and the round-trip preservation guarantee.
- MessageBuilder.cs: BuildBase eventTimestamp uses Constants.IsoTimestampFormat.
- Json.cs: float and double serialisation use Constants.RoundTripNumberFormat.
- AudienceSample.UI.cs: log-row export timestamp uses Constants.IsoTimestampFormat.
Names the wire-format JSON keys for the messages POST envelope, the messages POST response, and the
consent-sync PUT body, so runtime emit and test assert read from the same source.

- Constants.cs: adds ResponseFields (MessagesEnvelope, Rejected) for the messages POST envelope and
  the rejected-count response key.
- Constants.cs: adds ConsentBodyFields (Status, Source) for the tracking-consent PUT body.
- HttpTransport.cs: BuildPayload writes the envelope under ResponseFields.MessagesEnvelope;
  ParseRejectedCount reads ResponseFields.Rejected.
- ImmutableAudience.cs: SyncConsentLevel writes the PUT body under ConsentBodyFields.Status /
  Source.
- HttpTransportTests.cs: MockHandler responses and StringAssert.StartsWith fixtures read from
  ResponseFields.MessagesEnvelope / Rejected.
- ConsentSyncTests.cs: PUT body asserts read from ConsentBodyFields.Status / Source and derive the
  expected status string from ConsentLevel.ToLowercaseString.
Adds the 15 wire-format envelope keys callers reach for (eventName, anonymousId, identityType,
traits, messageId, eventTimestamp, context, surface, library, libraryVersion, fromId, fromType,
toId, toType, properties), and routes runtime emit and downstream callers through the new constants.

- Constants.cs: MessageFields gains the new envelope keys, grouped by section (envelope / track /
  identity / alias / context).
- MessageBuilder.cs: BuildBase, Track, Identify, Alias all read keys from MessageFields.
- ImmutableAudience.cs: DeleteData query string and consent-sync body anonymousId go through
  MessageFields; context-overlay TryGetValue reads MessageFields.Context.
- AudienceSample.cs: typed/string/custom event echo, identify form, and alias form go through
  MessageFields.Properties / IdentityType / Traits.
- Test suite (MessageBuilderTests, ImmutableAudienceTests, ConsentSyncTests, JsonReaderTests,
  JsonTests, EventQueueTests, DeleteDataTests): bracket-style envelope key access reads from
  MessageFields.
Names the auto-fired and typed event-name strings so runtime emit and the sample-app catalogue read
from one place.

- Constants.cs: adds EventNames with SessionStart, SessionEnd, SessionHeartbeat, GameLaunch,
  Progression, Resource, Purchase, MilestoneReached.
- Session.cs: SafeTrack calls for session_start / session_end / session_heartbeat read from
  EventNames.
- ImmutableAudience.cs: auto-fired game_launch event reads from EventNames.GameLaunch.
- TypedEvents.cs: Progression / Resource / Purchase / MilestoneReached EventName properties read
  from EventNames.
- AudienceSample.Events.cs: typed-event catalogue and the BuildTypedEvent dispatch read from
  EventNames.
Names the per-event property dictionary keys used by Session, TypedEvents, and the sample-app
catalogue.

- Constants.cs: adds EventPropertyKeys grouped by owning event (shared keys, Progression, Resource,
  Purchase, MilestoneReached).
- Session.cs: SessionStart / SessionEnd / SessionHeartbeat property dictionaries read keys from
  EventPropertyKeys.
- TypedEvents.cs: Progression / Resource / Purchase / MilestoneReached ToProperties dictionaries
  read keys from EventPropertyKeys.
- AudienceSample.Events.cs: typed event-spec EventField names read from EventPropertyKeys.
Names the per-event context dictionary keys and the auto-fired game_launch property keys, and routes
DeviceCollector's twelve truncation sites through Constants.MaxFieldLength so the 256-char cap reads
as a contract.

- Constants.cs: adds ContextKeys (UserAgent, Timezone, Locale, Screen) and GameLaunchPropertyKeys
  (Platform, Version, BuildGuid, UnityVersion, OsFamily, DeviceModel, Gpu, GpuVendor, Cpu, CpuCores,
  RamMb, ScreenDpi, DistributionPlatform).
- DeviceCollector.cs: CollectContext writes ContextKeys; CollectGameLaunchProperties writes
  GameLaunchPropertyKeys; truncation calls use Constants.MaxFieldLength.
- ImmutableAudience.cs: distribution-platform overlay on game_launch reads
  GameLaunchPropertyKeys.DistributionPlatform.
@ImmutableJeffrey ImmutableJeffrey force-pushed the chore/sdk-272-pr-1-sdk-runtime-constants branch from 34d4050 to 994279f Compare May 3, 2026 07:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant